#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "input_stuff.h"


static int search_table(const char *str, input_argu_t *table) {
	int index = 0;
	
	while (1) 
	{
		if( table[index].fixed == NULL )
		{
			return -1;
		}
		if( strcmp(str, table[index].fixed) == 0 )
		{
			return index;
		}
		index ++;
	}
}

static void mallocTable(input_argu_t *table) 
{
	int index = 0;
	
	while (1) 
	{
		if( table[index].fixed == NULL )
		{
			break;
		}
		if( (table[index].t == DEC) || (table[index].t == HEX) || (table[index].t == MRK) )
		{
			table[index].value = (void *)malloc(sizeof(unsigned int));
		}
		else if(table[index].t == STR)
		{
			table[index].value = malloc(STR_VALUE_LENGTH);		
		}
		index ++;
	}	
}

static void freeTable(input_argu_t *table) 
{
	int index = 0;
	
	while (1) 
	{
		if( table[index].fixed == NULL )
		{
			break;
		}
		if(table[index].value)
		{
			free(table[index].value);
		}
		index ++;
	}
}

int isThatReady(const char *fixed, input_argu_t *table, input_argu_t **id)
{
	int index = 0;
	
	while (1) {
		if( table[index].fixed == NULL )
		{
			return -1;
		}
		if( strcmp(fixed, table[index].fixed) == 0 )
		{
			if(table[index].filled)
			{
				if (id)
				{
					*id = &table[index];
				}
				return 1;
			}
			else
			{
				return 0;
			}
		}
		index ++;
	}
}

int catchInput(int argc, char **argv, input_argu_t *table, const char head) {
	int i;
	int index;
	int error = 0;
	
	mallocTable(table);
	
	for(i = 0; i < argc;) 
	{
		if(argv[i][0] == head) 
		{
			//printf("argv[%d][1]=%s\n", i, &argv[i][1]);
			index = search_table(&argv[i ++][1], table);
			//printf("index=%d\n", index);
			if(index != -1) {
				if (table[index].t != MRK)
				{
					if (strlen(argv[i]) >= STR_VALUE_LENGTH) 
					{
						printf("windbag input '%s'\n", argv[i]);
						argv[i][STR_VALUE_LENGTH - 1] = '\0';
					} 
					strcpy(table[index].str, argv[i ++]);
				} 
				
				if(table[index].value) 
				{
					switch(table[index].t) {
					case DEC:
						if(sscanf(table[index].str, "%d", (int *)table[index].value) != 1) 
						{
							printf("uknown input value '%s'\n", table[index].str);							
							error ++;					
						}
						else 
						{
							table[index].filled = 1;						
						}
						break;
					case HEX:
						if(sscanf(table[index].str, "%x", (unsigned int *)table[index].value) != 1)
						{
							printf("uknown input value '%s'\n", table[index].str);
							error ++;
						} 
						else 
						{
							table[index].filled = 1;
							//printf("value=0x%x\n", *(unsigned int *)table[index].value);
						}	
						break;
					case STR:
						strcpy(table[index].value, table[index].str);
						table[index].filled = 1;
						break;
					case MRK:
						*((int *)table[index].value) = 1;
						table[index].filled = 1;						
						break;
					case UDF:
						break;
					default:
						printf("unknown input type!\n");
					}
				}
			} 
			else 
			{
				error ++;
				printf("unrecognized option ‘%s'\n", argv[i - 1]);  
			}
		} else {
			i ++;
		}
	}	
	return error;
}

void unlatchInput(input_argu_t *table)
{
	freeTable(table);
}

// return 0 for success, > 0 for error count 
int read_input_stuff(int argc, char **argv, input_argu_t *table, const char head) {
	int i;
	int index;
	int error = 0;
	
	mallocTable(table);
	
	for(i = 0; i < argc;) {
		if(argv[i][0] == head) {
			//printf("argv[%d][1]=%s\n", i, &argv[i][1]);
			index = search_table(&argv[i ++][1], table);
			//printf("index=%d\n", index);
			if(index != -1) {
				if (table[index].t != MRK) {
					strcpy(table[index].str, argv[i ++]);
				} 
				if(table[index].value) {
					switch(table[index].t) {
					case DEC:
						if(sscanf(table[index].str, "%d", (int *)table[index].value) != 1) {
							printf("uknown input value '%s'\n", table[index].str);							
							error ++;					
						} else {
							table[index].filled = 1;						
						}
						break;
					case HEX:
						if(sscanf(table[index].str, "%x", (unsigned int *)table[index].value) != 1) {
							printf("uknown input value '%s'\n", table[index].str);
							error ++;
						} else {
							table[index].filled = 1;
						}	
						break;
					case STR:
						if( strlen(table[index].str) >= STR_VALUE_LENGTH ) {
							table[index].str[STR_VALUE_LENGTH - 1] = 0;
						}
						strcpy(table[index].value, table[index].str);
						table[index].filled = 1;
						break;
					case MRK:
						*((int *)table[index].value) = 1;
						table[index].filled = 1;						
						break;
					case UDF:
						break;
					default:
						printf("unknown input type!\n");
					}
				}
			} else {
				error ++;
				printf("unrecognized option ‘%s'\n", argv[i - 1]);  
			}
		} else {
			i ++;
		}
	}	
	return error;
}
